package org.footito.android.data.update;

import java.io.BufferedInputStream;
import java.io.StringReader;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.GregorianCalendar;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.util.ByteArrayBuffer;
import org.footito.android.api.CommentApiHandler;
import org.footito.android.api.EventApiHandler;
import org.footito.android.api.TeamListApiHandler;
import org.footito.android.application.FootitoApplication;
import org.footito.android.data.Team;
import org.footito.android.data.database.ProviderAdapter;
import org.footito.android.tools.Settings;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.content.Context;
import android.util.Log;

public abstract class DataManager {
	private static final String TAG = "DataManager";

	private static String downloadXML(HttpClient client, URL url, UpdateListener listener)
			throws Exception {
		String res = "";
		// Utils.debugger.logInfo(TAG, "Download start");

		HttpResponse response = null;
		BufferedInputStream bis = null;

		try {
			URI uri = url.toURI();
			HttpPost request = new HttpPost(uri);

			response = client.execute(request);
			long length = response.getEntity().getContentLength();
			long tenPercent = length / 10;
			if (tenPercent < 1)
				tenPercent = 1;
			bis = new BufferedInputStream(response.getEntity().getContent());

			if (response.getStatusLine().getStatusCode() != 200)
				throw new Exception();

			int cis = 0;
			ByteArrayBuffer baf = new ByteArrayBuffer(50);
			long i = 0;
			while ((cis = bis.read()) != -1) {
				baf.append((byte) cis);
				i++;
				if (length > 0) {
					long div = (i / tenPercent) * 10;
					long modulo = i % tenPercent;
					if (modulo == 0) {
						listener.onProgress(new Integer[] { UpdateListener.DOWNLOAD_PROGRESS,
								(int) div });
					}
				}
			}

			bis.close();

			res = new String(baf.toByteArray());
		} catch (Exception e) {

			if (bis != null) {
				try {
					bis.close();
				} catch (Exception e1) {
				}
			}

			throw (e);
		}

		return res;
	}

	private static void refreshCommentsFromServer(HttpClient client, Context context,
			ProviderAdapter db, UpdateListener listener) throws Exception {
		if (listener != null)
			listener.onProgress(new Integer[] { UpdateListener.COMMENTSLOADINGSTARTED });
		URL url;
		/* Create a URL we want to load some xml-data from. */
		if (Settings.getLastCheck(context).equals("")) {
			url = new URL(CommentApiHandler.URL_API);
		} else {
			url = new URL(CommentApiHandler.URL_API + "?"
					+ CommentApiHandler.URL_API_PUBLISHED_AFTER + "="
					+ Settings.getLastCheck(context));
		}

		Log.d("Footito", url.toString());
		String xml = downloadXML(client, url, listener);

		/* Get a SAXParser from the SAXPArserFactory. */
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser sp = spf.newSAXParser();

		/* Get the XMLReader of the SAXParser we created. */
		XMLReader xr = sp.getXMLReader();

		/* Create a new ContentHandler and apply it to the XML-Reader */
		CommentApiHandler commentApiHandler = new CommentApiHandler(db);
		xr.setContentHandler(commentApiHandler);

		/* Parse the xml-data from our URL. */
		xr.parse(new InputSource(new StringReader(xml)));

		if (listener != null)
			listener.onProgress(new Integer[] { UpdateListener.COMMENTSLOADINGOK });
	}

	private static void refreshEventsFromServer(HttpClient client, Context context,
			ProviderAdapter db, UpdateListener listener) throws Exception {
		RefreshEventParams params = new RefreshEventParams(Settings.getLastCheck(context), -1, -1,
				-1);
		refreshEventsFromServerParams(client, context, db, listener, params);
	}

	public static void refreshEventsFromServerParams(HttpClient client, Context context,
			ProviderAdapter db, UpdateListener listener, RefreshEventParams params)
			throws Exception {
		if (listener != null)
			listener.onProgress(new Integer[] { UpdateListener.EVENTLOADINGSTARTED });

		StringBuilder urlstring = new StringBuilder(EventApiHandler.URL_API + "?");
		if (params != null) {

			if (params.getPublishAfter() != null)
				urlstring.append(EventApiHandler.URL_API_PUBLISHED_AFTER + "="
						+ params.getPublishAfter() + "&");

			if (params.getLimit() > -1)
				urlstring.append("limit=" + params.getLimit() + "&");

			if (params.getOffset() > -1)
				urlstring.append("offset=" + params.getOffset() + "&");

			if (params.getTeamId() > -1)
				urlstring.append("team=" + params.getTeamId() + "&");

		}
		URL url = new URL(urlstring.toString());
		/* Create a URL we want to load some xml-data from. */
		// if (Settings.getLastCheck(context).equals("")) {
		// url = new URL(EventApiHandler.URL_API + "?limit=40");
		// } else {
		// url = new URL(EventApiHandler.URL_API + "?" +
		// EventApiHandler.URL_API_PUBLISHED_AFTER
		// + "=" + Settings.getLastCheck(context));
		// }
		Log.d("Footito", url.toString());
		String xml = downloadXML(client, url, listener);

		/* Get a SAXParser from the SAXPArserFactory. */
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser sp = spf.newSAXParser();

		/* Get the XMLReader of the SAXParser we created. */
		XMLReader xr = sp.getXMLReader();

		/* Create a new ContentHandler and apply it to the XML-Reader */
		EventApiHandler eventApiHandler = new EventApiHandler(db);
		xr.setContentHandler(eventApiHandler);

		/* Parse the xml-data from our URL. */
		xr.parse(new InputSource(new StringReader(xml)));
		if (listener != null)
			listener.onProgress(new Integer[] { UpdateListener.EVENTLOADINGOK });
	}

	public static void updateDataFromServer(Context context, UpdateListener listener)
			throws Exception {
		HttpClient httpclient = FootitoApplication.getApplicationInstance().getConnexion().getHttpClient();

		ProviderAdapter pa = new ProviderAdapter(context);
		try {
			updateTeamDBFromServer(httpclient, context, pa, listener);
			refreshEventsFromServer(httpclient, context, pa, listener);
			refreshCommentsFromServer(httpclient, context, pa, listener);
			Settings.setLastCheck(context, new GregorianCalendar());
		} catch (Exception e) {
			throw e;
		}

		// if (httpclient instanceof AndroidHttpClient) {
		// ((AndroidHttpClient) httpclient).close();
		// }
	}

	private static void updateTeamDBFromServer(HttpClient client, Context context,
			ProviderAdapter db, UpdateListener listener) throws Exception {
		if (listener != null)
			listener.onProgress(new Integer[] { UpdateListener.TEAMLOADINGSTARTED });
		/* Create a URL we want to load some xml-data from. */
		URL url;
		if (Settings.getLastTeamCheck(context).equals("")) {
			url = new URL(TeamListApiHandler.URL_API);
		} else {
			url = new URL(TeamListApiHandler.URL_API + "?"
					+ TeamListApiHandler.URL_API_UPDATED_AFTER + "="
					+ Settings.getLastTeamCheck(context));
		}
		Log.d("Footito", url.toString());
		String xml = downloadXML(client, url, listener);

		/* Get a SAXParser from the SAXPArserFactory. */
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser sp = spf.newSAXParser();

		/* Get the XMLReader of the SAXParser we created. */
		XMLReader xr = sp.getXMLReader();

		/* Create a new ContentHandler and apply it to the XML-Reader */
		TeamListApiHandler teamApiHandler = new TeamListApiHandler(db);
		xr.setContentHandler(teamApiHandler);

		/* Parse the xml-data from our URL. */
		xr.parse(new InputSource(new StringReader(xml)));
		Settings.setLastTeamCheck(context, new GregorianCalendar());
		if (listener != null)
			listener.onProgress(new Integer[] { UpdateListener.TEAMLOADINGOK });

	}

	public static void updatingCompleteProcess(Context context, UpdateListener listener) {

		if (listener != null)
			listener.onProgress(new Integer[] { UpdateListener.UPDATESTARTED });

		try {
			DataManager.updateDataFromServer(context, listener);
			DataManager.clearTooOldPosts();
		} catch (Exception e) {
		}

		// DataManager.updateDataFromDB(context, listener);
	}

	private static void clearTooOldPosts() {
		// TODO Auto-generated method stub
		
	}

	public void updateTeamsPicture(Context context) {
		ProviderAdapter db = new ProviderAdapter(context);
		ArrayList<Team> teams = db.getTeams();

		for (int i = 0; i < teams.size(); i++) {
			Team team = teams.get(i);
			int idTeam = team.getId();
		}

		// private void updateTeamsPicture() {
		// String[] projection = new String[] { COL_TEAM_ID, COL_TEAM_PICTURE };
		// String selection = null;
		//
		// Cursor c = db.query(TABLE_TEAMS, projection, selection, null, null,
		// null, null);
		//
		// while (c.moveToNext()) {
		// int idTeam = c.getInt(c.getColumnIndex(COL_TEAM_ID));
		// String targetPath = Team.PICTURE_FOLDER;
		// String targetName = idTeam + "";
		//
		// Bitmap bitmap = BitmapFactory.decodeFile(targetPath + targetName);
		// if (bitmap == null) {
		// LoadAsyncTask taskLoadPicture = new LoadAsyncTask(targetPath,
		// targetName, getTeam(idTeam));
		// taskLoadPicture.execute((Void[]) null);
		// } else {
		// getTeam(idTeam).setPicture(bitmap);
		// }
		// }
		// c.close();
		// }
	}
}
